package com.katian.metro;

import com.katian.FileInfo;
import com.katian.FileMeta;
import com.katian.UploadFiles;
import com.katian.chep.palettes.Client;
import com.katian.chep.palettes.Commande;
import com.katian.chep.palettes.RapportUtilisationChepPalletUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/metro")
public class MetroController {
    public static final String FILES = "files";
    public static final String RESULT = "result";

    protected final Log logger = LogFactory.getLog(getClass());

    @RequestMapping(method = RequestMethod.GET)
    public String printWelcome(ModelMap model) {
        model.addAttribute(FILES, getFileNames());
        model.addAttribute(RESULT, getResultFileName());
        return "metro";
    }

    @RequestMapping(value = "/get.commandes.file.name", method = RequestMethod.GET)
    @ResponseBody
    public FileInfo getFileNames() {
        return getFileNames(FILES);
    }


    @RequestMapping(value = "/get.result.file.name", method = RequestMethod.GET)
    @ResponseBody
    public FileInfo getResultFileName() {
        return getFileName(RESULT);
    }

    @RequestMapping(value = "/clear.files", method = RequestMethod.POST)
    @ResponseBody
    public void clearFiles() throws IOException {
        String filePath = getFilePath(FILES);
        File file = new File(filePath);
        if (file.exists()) {
            FileUtils.forceDelete(file);
        }
    }

    @RequestMapping(value = "/upload.files", method = RequestMethod.POST)
    @ResponseBody
    public List<FileMeta> uploadCommandes(@ModelAttribute(value = "FORM") UploadFiles files, BindingResult result) {
        return handleNewFile(files, result, FILES);
    }

    @RequestMapping(value = "/get.result.file", method = RequestMethod.GET)
    public void getResultFile(HttpServletResponse response) throws IOException {
        FileInfo resultFileName = getResultFileName();
        if (resultFileName != null) {
            File resultFile = new File(getFilePath(RESULT) + File.separator + resultFileName.getFileName());
            if (resultFile.exists()) {
                response.setContentType("application-xdownload");
                response.setHeader("Content-Disposition", "attachment; filename=\"" + resultFile.getName() + "\"");

                FileInputStream fileInputStream = new FileInputStream(resultFile);
                IOUtils.copy(fileInputStream, response.getOutputStream());
                fileInputStream.close();
                response.flushBuffer();

            }
        }
    }

    @RequestMapping(value = "/generate", method = RequestMethod.GET)
    @ResponseBody
    public String generate() throws IOException, ParseException {
        String folderPath = getFilePath(RESULT);
        File folder = new File(folderPath);
        if (folder.exists()) {
            FileUtils.cleanDirectory(folder);
        } else {
            FileUtils.forceMkdir(folder);
        }

        System.out.println("get clients");
        File[] files = getFiles(FILES);
        InputStream[] inputs = null;
        if (files != null) {
            inputs = new InputStream[files.length];
            for (int i = 0; i < files.length; i++) {
                inputs[i] = new FileInputStream(files[i]);
            }
        }


        File file = new File(folder.getAbsolutePath() + File.separator + "Facturation Globale.csv");

        MetroUtil.mergeFiles(new FileOutputStream(file), inputs);


        return "cool";
    }

    private List<FileMeta> handleNewFile(UploadFiles files, BindingResult result, String folderName) {
        List<FileMeta> fileMetas = null;
        if (!result.hasErrors()) {
            try {
                String folderPath = getFilePath(folderName);
                File folder = new File(folderPath);
                if (!folder.exists()) {
                    FileUtils.forceMkdir(folder);
                }

                CommonsMultipartFile multipartFile = files.getFile();

                FileMeta fileMeta = new FileMeta();
                fileMeta.setFileName(multipartFile.getName());
                fileMeta.setFileType(multipartFile.getContentType());
                fileMeta.setFileSize(multipartFile.getSize() / 1024 + " Kb");
                if (fileMetas == null) {
                    fileMetas = new ArrayList<>();
                }
                fileMetas.add(fileMeta);

                String filePath = folderPath + File.separator + com.katian.FileUtils.getValidFileName(multipartFile.getOriginalFilename());

                File file = new File(filePath);
                multipartFile.getFileItem().write(file);
            } catch (Exception e) {
                logger.error("Can't save file", e);
            }
        }

        return fileMetas;
    }

    private String getFilePath(String fileName) {
        return System.getProperty("java.io.tmpdir") + File.separator + "metro" + File.separator + fileName;
    }

    private FileInfo getFileName(String folderName) {
        FileInfo info = new FileInfo();
        File file = getFile(folderName);
        if (file != null) {
            info.setFileName(file.getName());
        }
        return info;
    }

    private File getFile(String folderName) {
        File file = null;
        String folderPath = getFilePath(folderName);
        File folder = new File(folderPath);
        if (folder.exists()) {
            File[] files = folder.listFiles();
            if (files != null && files.length > 0) {
                file = files[0];
            }
        }
        return file;
    }

    private FileInfo getFileNames(String folderName) {
        FileInfo info = new FileInfo();
        File[] files = getFiles(folderName);
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                String fileName = info.getFileName();
                if (fileName == null) {
                    info.setFileName(files[i].getName());
                } else {
                    info.setFileName(fileName + ", " + files[i].getName());
                }

            }
        }
        return info;
    }

    private File[] getFiles(String folderName) {
        File[] files = null;
        String folderPath = getFilePath(folderName);
        File folder = new File(folderPath);
        if (folder.exists()) {
            files = folder.listFiles();
        }
        return files;
    }
}